/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package it.polimi.registration.business.security.boundary;

import it.polimi.registration.business.security.entity.Friend;
//import it.polimi.registration.business.security.entity.Friend_;
import it.polimi.registration.business.security.entity.GroupFriend;
import it.polimi.registration.business.security.entity.SystemNotification;
import it.polimi.registration.business.security.entity.User;
import it.polimi.registration.gui.security.ResearchBean;
import static java.lang.Boolean.FALSE;
import static java.lang.Boolean.TRUE;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;

/**
 *
 * @author Innotommy91
 */

@Stateless
public class NotificationManager
{
    @PersistenceContext
    EntityManager em;
    
    @EJB
    private UserManager um;
     
    private Object JsfUtil;
    private List<Friend> fl;
    private Friend f;
    private GroupFriend gf;
    private User u1;
    
  public void save2(GroupFriend gl)
  {
      System.out.println("Salvataggio gl");
      em.persist(gl);
  }
  
   public void save3(Friend f)
  {
      System.out.println("Salvataggio friend");
      em.persist(f);
  }
  
      public void delete2(GroupFriend gl)
  {
      
      TypedQuery<GroupFriend> query = em.createQuery("SELECT e FROM GroupFriend e Where e.owner = :mail AND e.name=:name", GroupFriend.class);
                query.setParameter("mail",gl.getOwner());
                query.setParameter("name",gl.getName());
                
      System.out.println("cancella gl");
      gl=query.getSingleResult();
      em.remove(gl);
  }

  public void RequestResponse(int response,User amico)
  {
    User user;
    TypedQuery<User> query4 = em.createQuery("SELECT e FROM User e Where e.email = :mail", User.class);
                query4.setParameter("mail",amico.getEmail());
                user=query4.getSingleResult();
    System.out.println("ho ricevuto l'utente "+user.getName());
    u1=um.getLoggedUser();
    if(response==1) //accetto la richiesta di amicizia
    { 
        TypedQuery<Friend> query = em.createQuery("SELECT e FROM Friend e Where e.receiver = :mail AND e.sender =:name AND e.unread=:unread ORDER BY e.creationTime", Friend.class);
            query.setParameter("mail",u1);
            query.setParameter("name",amico);
            query.setParameter("unread",TRUE);
            fl = query.getResultList();//seleziono l'ultimo elemento della lista cioè il più recente che sarà la notifica di mio interesse
            f=fl.get(fl.size()-1);
            //flag letto sarà camabiato al momento della visualizzazione della notifica un set qua è ripetitivo
            if(f.getAzione()==1)   //notifica normale 
            {
                TypedQuery<GroupFriend> query2 = em.createQuery("SELECT e FROM GroupFriend e Where e.name = :nomegruppo AND e.owner =:proprietario", GroupFriend.class);
                    query2.setParameter("nomegruppo","lista_amici");
                    query2.setParameter("proprietario",u1);
                    gf=query2.getSingleResult();
                    gf.setBelongers(amico);
                    
                //ho aggiunto l'amico al mio gruppo ora mi aggiungo al suo gruppo di amici
                    
                TypedQuery<GroupFriend> query3 = em.createQuery("SELECT e FROM GroupFriend e Where e.name = :nomegruppo AND e.owner =:proprietario", GroupFriend.class);
                    query3.setParameter("nomegruppo","lista_amici");
                    query3.setParameter("proprietario",amico);
                    gf=query3.getSingleResult();
                    gf.setBelongers(u1);
                    
                Friend f2;
                f2 = new Friend();
                f2.setAzione(10);
                f2.setReceiver(f.getReceiver());
                f2.setSender(f.getSender());
                f2.setCreationTime(f.getCreationTime());
                f2.setUnread(FALSE);
                em.remove(f);
                em.flush();
                em.persist(f2);       
            }
            else if(f.getAzione()==-32)  //utente richiedente cancellato
            {
                System.out.println("utente richiedente cancellato riporto errore e non aggiungo al gruppo default");
               
                //modifico la notifica per dire che ho letto la notifica almeno se un nuovo utente usa la mia vecchia mail funziona tutto
                Friend f2;
                f2 = new Friend();
                f2.setReceiver(f.getReceiver());
                f2.setSender(f.getSender());
                f2.setCreationTime(f.getCreationTime());
                f2.setUnread(FALSE);
                em.remove(f);
                em.flush();
                em.persist(f2); 
                
            }
    }
    else if(response==0) //non interessa il caso di utente cancellato tanto non lo accetto può esistere o no chissene 
    {
        TypedQuery<Friend> query = em.createQuery("SELECT e FROM Friend e Where e.receiver = :mail AND e.sender =:name ORDER BY e.creationTime", Friend.class);
            query.setParameter("mail",u1);
            query.setParameter("name",amico);
            try{
                fl = query.getResultList();
                //prendo l'ultimo elemento essendo la notifica che mi interessa cancellare
                f=fl.get(fl.size()-1);
                Friend f2;
                f2 = new Friend();
                f2.setReceiver(f.getReceiver());
                f2.setSender(f.getSender());
                f2.setCreationTime(f.getCreationTime());
                f2.setUnread(FALSE);
                em.remove(f);
                em.flush();
                em.persist(f2);
            }
            catch(NoResultException nre)
            {
                System.out.println("non ho trovato tuple tra user: "+u1.getName()+"e user2: "+ amico.getName());
            }      
    }
  }
  
  
  public void changeAction(User receiver,int azione)
  {
   CriteriaBuilder cb =em.getCriteriaBuilder();
   CriteriaQuery <Friend> cq= cb.createQuery(Friend.class);
   Root<Friend> friend =cq.from(Friend.class);
   //cq.where(cb.equal(friend.get(Friend_.receiver), receiver));
   //cq.orderBy(cb.asc(friend.get(Friend_.creationTime)));
   
   TypedQuery<Friend> query= em.createQuery(cq);
   List <Friend> result;
   result= query.getResultList();
   System.out.println(receiver.toString());
   int i;
   for(i=0;i<result.size();i++)
   {
    System.out.println(result.get(i).getReceiver().getEmail());
   }
   System.out.println(result.get(i-1).getReceiver().toString());
      
  }
    /**
     *
     * @return
     */
  
  /*
    public boolean checkFriendRequest()
  {
    User local=rb.getSearchedUser();
    User local2=um.getLoggedUser();
    TypedQuery<Friend> query = em.createQuery("SELECT e FROM Friend e Where e.sender = :mail AND e.receiver=: receiver", Friend.class);
        query.setParameter("mail",local2);
        query.setParameter("receiver",local);
        Friend gf;
        gf = query.getSingleResult(); //la quesry se esiste restituisce un solo valore se non restituisce non ho richieste pendenti
    if(gf==null)
    {
        return FALSE;
    }   
    return TRUE;
  }
  */
  

  
  
  
    /**
     *funcion that receive from the notificationbean the receiver user for the friendship request
     * and the sender user is determinated by asking who is the logged user at the moment of the request
     * @param receiver
     */
  
    public void createFriendRequest(User receiver)
    {
        u1=um.getLoggedUser();
        Date date = new Date();
        Friend friendnotify = new Friend(u1,receiver,date,TRUE,1);
        em.persist(friendnotify);
    }
    
    public List<Friend> findFriendNotification(User user)
    {    
        TypedQuery<Friend> query = em.createQuery("SELECT i FROM Friend i Where i.receiver = :mail AND i.unread = :now", Friend.class);
            query.setParameter("mail",um.getUser(user.getEmail()));
            query.setParameter("now", TRUE);
        return query.getResultList();
        
    }
  
  
  /*
     public void create(Friend entity) 
    {
    ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
        javax.validation.Validator validator = factory.getValidator();
    Set<ConstraintViolation<Friend>> constraintViolations = validator.validate(entity);
    if(constraintViolations.size() > 0){
        Iterator<ConstraintViolation<Friend>> iterator = constraintViolations.iterator();
        while(iterator.hasNext()){
            ConstraintViolation<Friend> cv = iterator.next();
            System.err.println(cv.getRootBeanClass().getName()+"."+cv.getPropertyPath() + " " +cv.getMessage());

      JsfUtil.addErrorMessage(cv.getRootBeanClass().getSimpleName()+"."+cv.getPropertyPath() + " " +cv.getMessage());  
        }
    }
     }

   */
    
}
